<?php
namespace ITSociaal\Themes\Houtgrutter;

/* These methods should be static, but PHPUnit doesn't allow it:
 *
 *   "Please note that final, private and static methods cannot
 *    be stubbed or mocked.  They are ignored by PHPUnit's test
 *    double functionality and retain their original behavior."
 */
class Util
{
	/**
	 * Invokes the new operator for you :)
	 *
	 * @param string $class
	 *
	 * @return object
	 */
	public function createObject($class, $arg = null)
	{
		return new $class($arg);
	}

	/**
	 * Not orthogonal to deriveTemplatePathFromName
	 *
	 * @param string $path
	 *
	 * @return string Relative path to template
	 */
	public function deriveTemplateNameFromPath($path)
	{	// This could use some refactoring for robustness

		if (($path[0] === "/") || (substr($path, -4) === ".php")) {
			$comp = explode(
				realpath(theme_root_path()),
				realpath($path)
			);

			if (($comp[0] === "") && (isset($comp[1]))) {
				$ret = strtolower($comp[1]);
			}
		}
		else {
			$ret = $path;
		}

		$ret = ltrim(strtr($ret, "\\", "/"), "/");

		if (substr($ret, -4) === ".php") {
			$ret = substr($ret, 0, -4);
		}

		return $ret;
	}

	/**
	 * Derives a class name from a relative path
	 *
	 * @param string $name Template name
	 *
	 * @return string Possible name of a class
	 */
	public function deriveClassNameFromTemplateName($name)
	{
		$pieces = explode("/", strtolower($name));

		return __NAMESPACE__ . "\\" .
			str_replace(
				"-",
				"",
				implode(
					"\\",
					array_map(
						"ucwords",
						$pieces,
						array_fill(0, count($pieces), "-\\")
					)
				)
			);
	}

	/**
	 * Not orthogonal to deriveTemplateNameFromPath
	 *
	 * @param string $name      Template name
	 * @param string $extension Extension, e.g. ".md"
	 *
	 * @return string Possible path to a template
	 */
	public function deriveTemplatePathFromName($name, $extension = ".php")
	{
		$parts = explode("/", $name);
		$last = "templates/" . strtolower(array_pop($parts));
		$parts = array_map(function($part) {
			return str_replace("-", "", ucwords($part, "-"));
		}, $parts);
		$parts[] = $last;

		return SRCDIR . "/" . implode("/", $parts) . $extension;
	}

	/**
	 * array_map as a generator, with flipped arguments
	 *
	 * @param array    $args   Arguments passed to $method one by one
	 * @param callable $method Mapping function
	 *
	 * @return \Iterator yields return values of $method
	 */
	public function generateResultPerArgument(array $args, callable $method)
	{
		foreach ($args as $arg) {
			yield call_user_func($method, $arg);
		}
	}

	/**
	 * Same as generateResultPerArgument, but sideways
	 *
	 * @param array $methods Set of callables to iterate over
	 * @param mixed ...$args Optional arguments passed to $methods each time
	 *
	 * @return \Iterator yields return value of each callable
	 */
	public function generateResultPerMethod(array $methods, ...$args)
	{
		foreach ($methods as $method) {
			yield call_user_func_array($method, $args);
		}
	}
}

/* vi:set ts=4 sw=4 noet: */
